﻿
using Bridge.Shared.Extensions;
using Bridge.Shared.Models;
using Mapster;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using OrderVouchers.Input;
using Stock.Input;
using Stock.Output;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Vouchers.InStockVouchers;
using Vouchers.InStockVouchers.Input;
using Vouchers.InStockVouchers.Output;
using Zack.EFCore.Batch.Internal;
using Stock;
using Bridge.Shared.Enums.Wms;

namespace Vouchers
{

    [RemoteService(IsMetadataEnabled = false)]
    public class InStockVoucherService : ApplicationService, IInStockVoucherService, IInVoucherStockService
    {
        private readonly IRepository<InStockVoucher, Guid> _inStockRepository;
        private readonly IRepository<InStockVoucherDetail, Guid> _inStockDetailRepository;
        public InStockVoucherService(IRepository<InStockVoucher, Guid> inStockRepository,
                                     IRepository<InStockVoucherDetail,Guid> inStockDetailRepository)
        {
            _inStockRepository = inStockRepository;
            _inStockDetailRepository = inStockDetailRepository;
        }
       
        public async Task<List<InStockOutput>> GetInStock(GetStockInput input)
        {
            var query = from a in (await _inStockRepository.GetQueryableAsync())
                        join b in (await _inStockDetailRepository.GetQueryableAsync()) on a.VoucherCode equals b.VoucherCode
                        where input.VoucherCodes.Contains(a.VoucherCode)
                        select new InStockOutput
                        {
                            DeptId=a.WarehouseId,
                            DeptName = a.WarehouseName,
                            ProductCode = b.ProductCode,
                            ProductName = b.ProductName,
                            InStockCount = b.InCount,
                            Price = b.Price,
                            ProductBatch = b.ProductBatch,
                            ProductDate = b.ProductDate,
                            ExpiryDate = b.ExpiryDate,
                            TrackCode = b.TrackCode,
                            SupplierId=a.SupplierId,
                            SupplierName=a.SupplierName,
                            ProductClassName=a.ProductClassName,
                            ProductClassId=a.ProductClassId,
                            ManufactureId=b.ManufacturerId,
                            ManufactureName=b.ManufacturerName,
                            Specification=b.Specification,
                            UseUnit=b.Unit                           
                        };

            var dto =await query.ToListAsync();
            return dto;

        }
       public async Task<ResponseResult> SubmitInStockVoucher(List<Guid> input)
        {
            var query = await _inStockRepository.GetQueryableAsync();
            var voucherList = await query.Where(a => input.Contains(a.Id)).ToListAsync();
            foreach (var voucher in voucherList) { 
            
                if(!voucher.Status.IsIn(new List<OrderStatusEnum>() { OrderStatusEnum.Temporary, OrderStatusEnum.Rejected }))
                {
                    ResponseResult.Fail($"单据【{voucher.VoucherCode}】不是暂存或驳回状态无法提交");
                }

                voucher.Status = OrderStatusEnum.Submit;
            
            }
            await _inStockRepository.UpdateManyAsync(voucherList);
            return ResponseResult.Success("操作成功！");
        }

        /// <summary>
        /// 创建或修改入库单
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<ResponseResult> CreateOrUpdate(CreateOrUpdateInStockVoucherInput input)
        {
            var inStockvoucherDetailList = new List<InStockVoucherDetail>();
            if (!input.Id.HasValue)
            {
                var inStockvoucher = new InStockVoucher();
                

                inStockvoucher = input.Adapt<InStockVoucher>();
                var mainId = GuidGenerator.Create();
                inStockvoucher.SetId(mainId);

              

              await  _inStockRepository.InsertAsync(inStockvoucher);
             
            }
            else
            {
                var inStockVoucher = await _inStockRepository.FirstOrDefaultAsync(a=>a.Id == input.Id.Value);
                if(inStockVoucher == null)
                {
                    return ResponseResult.Fail("记录不存在！");
                }
                inStockVoucher.Purchaser = input.Purchaser;
                await _inStockRepository.UpdateAsync(inStockVoucher);

            }

            inStockvoucherDetailList = input.inStockVoucherDetails.Adapt<List<InStockVoucherDetail>>();

            foreach (var item in inStockvoucherDetailList)
            {
                var detailId = GuidGenerator.Create();
                item.SetId(detailId);
            }

            await _inStockDetailRepository.InsertManyAsync(inStockvoucherDetailList);
            return ResponseResult.Success("操作成功！");

        }

        /// <summary>
        /// 获取入库单明细
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResponseResult<InStockVoucherDetailOutput>> GetDetailById(GetDetailInput input)
        {
            var inStockvoucher = await _inStockRepository.FirstOrDefaultAsync(x => x.Id == input.Id);
            if (inStockvoucher == null)
            {
                return PageResponseResult<InStockVoucherDetailOutput>.Fail("主表记录不存在！");
            }

            var totalCount = await _inStockDetailRepository.CountAsync(a => a.Id == input.Id);

            if (totalCount == 0)
            {
                return PageResponseResult<InStockVoucherDetailOutput>.Fail("明细记录不存在！");
            }

            var inStockvoucherDetailList = (await _inStockDetailRepository.GetQueryableAsync())
                                            .Where(a=>a.Id==input.Id)
                                            .Skip(input.PageSize*input.PageIndex).Take(input.PageSize)
                                            .ToList();
            var dto = inStockvoucherDetailList.Adapt<List<InStockVoucherDetailOutput>>();
            return PageResponseResult<InStockVoucherDetailOutput>.Success("ok", dto, input.PageSize,input.PageIndex,totalCount);
           
        }


        /// <summary>
        ///获取入库单分页数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResponseResult<InStockVoucherOutput>> GetPageList(GetInStockVoucherInput input)
        {
            var query = (await _inStockRepository.GetQueryableAsync())
                                    .WhereIf(input.StartTime.HasValue, a => a.CreationTime > input.StartTime)
                                    .WhereIf(input.EndTime.HasValue, a => a.CreationTime < input.EndTime);
            var totalCount = query.Count();
            if (totalCount == 0) {
                return PageResponseResult<InStockVoucherOutput>.Success("ok",null,input.PageSize,input.PageIndex,totalCount);
            }
            var inStockvoucherList = query
                                    .Skip(input.PageIndex*input.PageSize)
                                    .Take(input.PageSize)
                                    .OrderByDescending(a=>a.CreationTime)
                                    .ToList();

            var dto = inStockvoucherList.Adapt<List<InStockVoucherOutput>>();

            return PageResponseResult<InStockVoucherOutput>.Success("ok", dto, input.PageSize, input.PageIndex, totalCount);

        }
    }
}
